/**
 * thunk 做异步，主要是通过 createAsyncThunk() 创建一个异步的动作
 *
 *    语法：
 *      const 动作创建函数 = createAsyncThunk(name, 函数)
 *        1. name - 字符串，用于表示该动作前缀
 *                'hello'
 *                    'hello/pending'
 *                    'hello/fulfilled'
 *                    'hello/rejected'
 *        2. 函数 - 该函数需要是一个 Promise
 *                 函数接受到一个参数，调用该动作时，传递过来的参数
 *        3. 动作创建函数
 *              加括号使用
 *                动作创建函数()    => {type: 'xxx', payload: undefined}
 *                动作创建函数('张三')    => {type: 'xxx', payload: '张三'}
 *
 *    特点：
 *      调用时，会直接触发 Promise 函数，函数走完之后，会再去自动帮我们 dispatch 一些普通动作
 *        'hello/pending'
 *        'hello/fulfilled'
 *        'hello/rejected'
 */

import { createSlice, createAsyncThunk, PayloadAction } from "@reduxjs/toolkit";

interface IGood {
  id: number;
  name: string;
  price: string;
}

type AddGood = Pick<IGood, "name" | "price">;

// 通过 createAsyncThunk 来创建异步动作
export const fetchGoods = createAsyncThunk("cart/fetchGoods", async () => {
  // 该函数有个名称叫做 payloadCreator , 该函数的返回值，是一个 payload
  console.log("=== fetchGoods");
  const result = await fetch("http://localhost:3000/goods").then((response) =>
    response.json()
  );
  // throw new Error("hello");
  return result;
});

export const newGoods = createAsyncThunk<any, AddGood>(
  "cart/newGoods",
  async (params) => {
    console.log("params", params);
    const result = await fetch("http://localhost:3000/goods", {
      method: "POST",
      body: JSON.stringify(params),
      // fetch post 请求需要注意请求头中的 Content-Type 的设置
      headers: {
        "Content-Type": "application/json",
      },
    }).then((response) => response.json());
    console.log(result, "result");
    return result;
  }
);

// fetchGoods 是个动作创建函数，调用它的返回值是一个动作（异步动作）
// dispatch 触发该异步动作的话，就会执行该上面定义的 Promise 函数
// console.log(fetchGoods(), "===");

const cartSlice = createSlice({
  name: "cart",
  initialState: {
    loading: false, // 表示是否在请求接口
    goods: [] as IGood[],
  },
  reducers: {
    set_goods(state, { payload }: PayloadAction<IGood[]>) {
      state.goods = payload;
    },
  },

  // 额外的 reducers
  extraReducers: (builder) => {
    builder
      .addCase(fetchGoods.pending, (state) => {
        // 处理 fetchGoods pengding 状态时的一些逻辑
        console.log("pending");
        state.loading = true;
      })
      .addCase(fetchGoods.fulfilled, (state, action) => {
        // 处理 fetchGoods fulfilled 状态时的一些逻辑
        console.log("fulfilled", action.payload);
        state.goods = action.payload;
        state.loading = false;
      })
      .addCase(fetchGoods.rejected, () => {
        // 处理 fetchGoods rejected 状态时的一些逻辑
        console.log("rejected");
      })
      .addCase(newGoods.fulfilled, (state, action) => {
        console.log("newGoods.fulfilled", action.payload);
        // 将 action.payload 直接追加到 goods 中
        state.goods.push(action.payload);
      });
  },
});

export const { set_goods } = cartSlice.actions;

// 导出 slice 的 reducer
export default cartSlice.reducer;
